package top.caoayu;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import oshi.SystemInfo;
import oshi.software.os.OSProcess;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.Optional;
import java.util.Timer;
import java.util.TimerTask;

public class Main {
    private static final String PROCESS_NAME = "dwm"; // 替换成你要监听的进程名称
    private static final long MEMORY_THRESHOLD = 1024 * 1024 * 1000; // 内存阈值，单位为字节
    private static final Log log = LogFactory.get();

    /**
     * The main method is the entry point for the Java application.
     * It creates a Timer object and schedules a MemoryCheckTask to run every 30 seconds.
     * The MemoryCheckTask is responsible for checking the memory usage.
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new MemoryCheckTask(), 0, 30000); // 每秒检查一次内存使用情况
    }

    /**
     * 检查内存使用情况的任务
     * params: 无
     */
    private static class MemoryCheckTask extends TimerTask {
        @Override
        public void run() {
            long pid = getProcessId();
            if (pid != -1) {
                long memoryUsage = getProcessMemoryUsage(pid);
                Console.log("进程 ID: " + pid);
                Console.log("内存使用: " + NumberUtil.decimalFormat(",###",memoryUsage) + " bytes");

                if (memoryUsage > MEMORY_THRESHOLD) {
                    Console.log("内存使用超过阈值，终止进程：" + PROCESS_NAME);
                    killProcess(pid);
                }
            }
        }

private long getProcessId() {
            // 获取系统信息
            SystemInfo systemInfo = new SystemInfo();
            // 获取当前操作系统的进程信息
            Optional<OSProcess> osProcess =
                    systemInfo.getOperatingSystem().getProcesses().stream().filter(v -> PROCESS_NAME.equals(v.getName())).findFirst();
            // 返回进程ID
            return osProcess.map(OSProcess::getProcessID).orElse(-1);

        }

//获取进程内存使用量
private long getProcessMemoryUsage(long pid) {
            //获取内存管理工厂
            MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
            //获取堆内存使用量
            return memoryMXBean.getHeapMemoryUsage().getUsed();
        }

        private void killProcess(long pid) {
            // 根据操作系统执行相应的终止进程命令
            String os = System.getProperty("os.name").toLowerCase();
            String command;
            if (os.contains("win")) {
                command = "taskkill /F /PID " + pid;
            } else {
                command = "kill " + pid;
            }

            try {
                Runtime.getRuntime().exec(command);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}